/**
 * 给定一个非负整数数组nums，你最初位于数组的第一个下标
 * 数组中每个元素代表你在该位置能跳跃的最远距离
 * 判断你能否到达最后一个下标
 */

// 扩展：展示出路径

// 只要存在非0或者跳过0的位置，就一定可以到达，但如果不可避免的碰到0就一定到达不了

{
  // 第一种解法：遍历，n叉树最深，与数组长度对比，不断的开新线程/多维数组,广度再深度
  function jump1(nums: ReadonlyArray<number>) {
    let disassemblyNums = nums.map((item) => {
      if (item <= 1) {
        return item;
      }
      return [
        ...(function* displayRank(item) {
          for (let i = item; i > 0; i--) {
            yield i;
          }
        })(item),
      ];
    });

    disassemblyNums.map((item) => {
      if (item instanceof Number) {
        return item;
      }
      if (item instanceof Array) {
        item.map((innerItem) => {
          return innerItem;
        });
      }
    });
  }

  // 合并前后数据形成新的数组
  function iterationFun1(prev, next) {
    let arr = (typeof prev === "number" ? [prev] : prev).map((item) =>
      (typeof next === "number" ? [next] : next).map((innerItem) => [
        item,
        innerItem,
      ])
    );
    return [].concat(...arr);
  }
}

{
  /** 第二种解法：穷举法——从后往前/从前往后遍历，取最大值，不行再返回上一层取最大值减一，不断返回上一层或者直到成功，深度再广度
   * 引申出的多种解法，promise试图通过resolve跟reject转换所有权和返回上一级   promise顺着链下去的，并不能返回到上上层（返回到上一层是因为可以传递参数,实际没有返回功能）
   * for循环return退出和嵌套调用，尾调用而不是把作用域拉的很长
   * for循环非尾调用
   * 不转移所有权的解法
   */
}

{
  // 第三种解法，找到0的位置，往前遍历试图跳过，~zerrorArr.indexOf(index+nums[index])
  function jumpn(nums: ReadonlyArray<number>) {}
}

{
  // 第四种解法：打标记，只要能到达的就打标记，从头到尾遍历一遍只要最后一个能打到标记就对了（每一个位置都取最长） 连续不中断的标记
}

/**
 * 扩展知识点
 */
{
  // 尾递归
  function tailRecursion(resultArr: ReadonlyArray<number>, value: number) {
    if (value > 1) {
      return tailRecursion([...resultArr, value], --value);
    } else {
      return [...resultArr, 1];
    }
  }
}

{
  // 非尾递归
  function notTailRecursion(value: number) {
    if (value > 1) {
      return [value, ...notTailRecursion(--value)];
    } else {
      return [value];
    }
  }
}

/**
 * 数组扁平化
 */
{
  // 方案一
  // 想着怎么把any调整一下????
  const flatten = (arr: ReadonlyArray<any>) => {
    let result: number[] = [];
    for (let i = 0; i < arr.length; i++) {
      if (Array.isArray(arr[i])) {
        result = result.concat(flatten(arr[i]));
      } else {
        result.push(arr[i]);
      }
    }
    return result;
  };
}

{
  // 方案二
  const flatten = (arr) => {
    return arr.reduce((prev, next) => {
      return prev.concat(Array.isArray(next) ? flatten(next) : next);
    }, []);
  };
}

{
  // 方案三 ...
  const flatten = (arr) => {
    while (arr.some((item) => Array.isArray(item))) {
      arr = [].concat(...arr);
    }
    return arr;
  };
}

{
  // 方案四 split 和 toString 共同处理
  const flatten = (arr) => {
    return arr.toString().split(",");
  };
}

{
  // 方案五 调用 ES6 中的 flat
  let arr = [];
  arr.flat();
}

{
  // 方案六 正则和 JSON 方法共同处理
  const flatten = (arr) => {
    let str = JSON.stringify(arr);
    str = str.replace(/(\[|\])/g, "");
    str = `[${str}]`;
    return JSON.parse(str);
  };
}
